package com.yangyouli.unity_demo_server.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimerTask;

import com.alibaba.fastjson.JSONObject;
import com.yangyouli.unity_demo_server.server.serializeModel.MonsterStatus;
import com.yangyouli.unity_demo_server.server.serializeModel.StopPauseData;
import com.yangyouli.unity_demo_server.util.Generator;
import com.yangyouli.unity_demo_server.util.ThreadLocalHelper;

public class RoomObj {
	/**
	 * 有玩家结束对话后的指定时间如果还有玩家没有结束剧情对话，则强制结束剧情对话时间，单位毫秒
	 */
	public static final int MAX_WAIT_STOP_PAUSE_TIME = 10000;
	static final int MAX_PEOPLE_IN_ROOM = 8;
	// 进入下一段剧情需要杀的怪物总量
	private static final int needKillMonsterNumArray[] = {5, 7, 9, 11, 13, 15};
	
	private String roomId;
	private Client master;
	private int masterPosition; // 在房间中的位置索引
	private List<Client> clients;
	private List<Integer> clientsPosition; // 对应玩家在房间中的位置索引
	private boolean[] positionIsTaken; // 位置被占用情况，其索引对应 position 的具体值
	// 存储该队伍所在房间的所有物品的 itemId
	private List<String> items;
	// 怪物的状态 key 为怪物编号
	private Map<String, MonsterStatus> monsterMap;

	
	private int section = 0; // 当前任务进度
	private int killMonster = 0; // 杀怪总数
	private int currentKillMonster = 0; // 当前任务杀怪总数
	private int readyPeopleNum = 0; // 准备好的人数
	private boolean pause; // 是否暂停
	private long lastStopPauseTime = 0; // 上一次发送请求暂停时的时间戳，如果距离上一次发送取消暂停请求超过指定时间，则取消游戏暂停状态
	
	public class StopPauseTask extends TimerTask {
		@Override
		public void run() {
			if (System.currentTimeMillis() - lastStopPauseTime >= MAX_WAIT_STOP_PAUSE_TIME && pause) {
				int readyNum = getReadyPeopleNum();
				int totalNum = getClients() != null ? getClients().size() + 1 : 1;
				StopPauseData stopPauseData = new StopPauseData(readyNum, totalNum, getSection(), isPause());
				// 有玩家结束对话后的指定时间如果还有玩家没有结束对话，则强制结束对话
				master.getServer().sendToRoom("StopPauseForceRequest", JSONObject.toJSONString(stopPauseData), master);
				setPause(false);
			}
		}
	}
	
	private int maxPeople; // 最大人数
    private int mode; // 模式
	private boolean start;

	public RoomObj () {
		this.clients = new ArrayList<>();
		this.clientsPosition = new ArrayList<>();
		this.items = new ArrayList<>();
		this.monsterMap = new HashMap<>();
		this.positionIsTaken = new boolean[MAX_PEOPLE_IN_ROOM];
		this.maxPeople = MAX_PEOPLE_IN_ROOM;
	}

	public RoomObj(String roomId, Client master, int masterPosition) {
		this();
		this.roomId = roomId;
		this.master = master;
		this.masterPosition = masterPosition;
		this.positionIsTaken[masterPosition] = true;
	}

	/**
	 * 创建怪物
	 * @param id
	 * @param monsterStatus
	 */
	public void addMonster (String id, MonsterStatus monsterStatus) {
		synchronized (monsterMap) {
			monsterMap.put(id, monsterStatus);
		}
	}
	
	/**
	 * 
	 * @param id
	 * @param damageValue
	 * @return 返回减去伤害后怪物的生命，返回 -1 则表示找不到该 id 的怪物 (已经死亡，被移除)
	 */
	public int damageMonster (String id, int damageValue) {
		MonsterStatus z = monsterMap.get(id);
		if (z == null) return -1;
		
		synchronized (monsterMap) {
			z.setHp(z.getHp() - damageValue);
			if (z.getHp() <= 0) {
				// 杀死该怪物的玩家加经验和金
				Client client = ThreadLocalHelper.getClient();
				client.setAddExp(client.getAddExp() + Generator.Range(20, 50));
				client.setAddMoney(client.getAddMoney() + Generator.Range(5, 15));
				killMonster++;
				currentKillMonster++;
				monsterMap.remove(id);
				// 如果杀怪数量达到指定值，则触发对话
				/*if (section < needKillMonsterNumArray.length && needKillMonsterNumArray[section] == currentKillMonster) {
					currentKillMonster = 0;
					master.getServer().sendToRoom("B-StoryRequest", "" + (++section), master);
				}*/
			}
		}
		
		return z.getHp();
	}
	
	/**
	 * 玩家加入到队伍
	 * @param client
	 */
	public void addClient (Client client) {
		synchronized (client) {
			clients.add(client);
			clientsPosition.add(findFreePosition());
		}
	}
	
	/**
	 * 玩家退出队伍
	 * @param client
	 */
	public void removeClient (Client client) {
		int index = clients.indexOf(client);
		if (index >= 0) {
			synchronized (clients) {
				client.setRoomObj(null);
				clients.remove(index);
				positionIsTaken[clientsPosition.get(index)] = false;
				clientsPosition.remove(index);
			}
		}
	}
	
	public Client getClientByUserId (int userId) {
		for (Client c : clients) {
			if (c.getUserId() == userId) {
				return c;
			}
		}
		return null;
	}
	
	/**
	 * 解散队伍
	 */
	public void dissolveRoom () {
		roomId = "0";
	}

	/**
	 * 找到一个空闲的位置，返回其索引，为0 ~ 7
	 * @return
	 */
	private int findFreePosition () {
		// 分配一个位置
		for (int i = 0; i < positionIsTaken.length; i++) {
			if (!positionIsTaken[i]) {
				// 找到第一个为空的位置
				positionIsTaken[i] = true;
				return i;
			}
		}
		return -1;
	}
	
	public List<Client> getClientsAndMaster() {
		List<Client> allClients = new ArrayList<Client>();
		if (clients != null) {
			allClients.addAll(clients);
		}
		allClients.add(master);
		return allClients;
	}
	
	public int getAlivePlayerNum() {
		List<Client> clients = getClients();
		Client master = getMaster();
		int count = 0; // 存活人数
		if (master.getHp() > 0) {
			count++;
		}
		if (clients != null) {
			for (Client c : clients) {
				if (c.getHp() > 0) {
					count++;
				}
			}
		}
		return count;
	}
	
	public String getRoomId() {
		return roomId;
	}

	public void setRoomId(String roomId) {
		this.roomId = roomId;
	}

	public Client getMaster() {
		return master;
	}

	public void setMaster(Client master) {
		this.master = master;
		this.masterPosition = findFreePosition();
	}
	
	public void setMaster(Client master, int position) {
		this.master = master;
		this.masterPosition = position;
	}

	public List<Client> getClients() {
		return clients;
	}

	public void setClients(List<Client> clients) {
		this.clients = clients;
	}

	public List<String> getItems() {
		return items;
	}

	public void setItems(List<String> items) {
		this.items = items;
	}
	
	public Map<String, MonsterStatus> getMonsterMap() {
		return monsterMap;
	}

	public void setMonsterMap(Map<String, MonsterStatus> monsterMap) {
		this.monsterMap = monsterMap;
	}

	public int getMaxPeople() {
		return maxPeople;
	}

	public void setMaxPeople(int maxPeople) {
		this.maxPeople = maxPeople;
	}

	public int getMode() {
		return mode;
	}

	public void setMode(int mode) {
		this.mode = mode;
	}

	public boolean isStart() {
		return start;
	}

	public void setStart(boolean start) {
		this.start = start;
	}

	public int getMasterPosition() {
		return masterPosition;
	}

	public List<Integer> getClientsPosition() {
		return clientsPosition;
	}

	public boolean[] getPositionIsTaken() {
		return positionIsTaken;
	}

	public void setPositionIsTaken(boolean[] positionIsTaken) {
		this.positionIsTaken = positionIsTaken;
	}

	public void setMasterPosition(int masterPosition) {
		this.masterPosition = masterPosition;
	}
	
	public int getSection() {
		return section;
	}

	public void setSection(int section) {
		this.section = section;
	}
    public int getReadyPeopleNum() {
		return readyPeopleNum;
	}

	public void setReadyPeopleNum(int readyPeopleNum) {
		this.readyPeopleNum = readyPeopleNum;
	}
	public boolean isPause() {
		return pause;
	}

	public void setPause(boolean pause) {
		this.pause = pause;
	}

	public long getLastStopPauseTime() {
		return lastStopPauseTime;
	}

	public void setLastStopPauseTime(long lastStopPauseTime) {
		this.lastStopPauseTime = lastStopPauseTime;
	}

}
